﻿using DevelopAssistant.AddIn;
using DevelopAssistant.Common;
using System;
using System.Collections.Generic;
using System.Text;
 

namespace DevelopAssistant.Core
{
    public class Plug_in_Manager
    {
        string PluginSourcePath = string.Empty;
        string AssemblySourcePath = string.Empty;

        private static object lockObject = null;
        private static Plug_in_Manager _instance = null;
        public static Plug_in_Manager Instance
        {
            get
            {
                if (_instance == null)
                {
                    if (lockObject == null)
                    {
                        lockObject = new object();
                    }
                    lock (lockObject)
                    {
                        _instance = new Plug_in_Manager();
                    }
                }
                return _instance;
            }
        }

        public Plug_in_Manager()
        {
            //params
            PluginSourcePath = (AppDomain.CurrentDomain.BaseDirectory + "\\AddIn").Replace("\\\\", "\\");
            AssemblySourcePath = PluginSourcePath.Substring(0, PluginSourcePath.LastIndexOf("AddIn"));
        }

        public AddInBase Add(string AddInConfigure)
        {
            AddInBase addIn = new AddInBase();
            return addIn;
        }

        public void Remove(string id)
        {
            
        }

        public List<AddInBase> Load(ref string Message)
        {
            List<AddInBase> list = new List<AddInBase>();
            if (!System.IO.Directory.Exists(PluginSourcePath))
                System.IO.Directory.CreateDirectory(PluginSourcePath);

            string[] PluginsFiles = System.IO.Directory.GetFiles(PluginSourcePath, "*.AddIn");

            try
            {
                foreach (string file in PluginsFiles)
                {
                    AddInBase plugin = new AddInBase();
                    System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
                    XmlDoc.Load(file);

                    //...                    
                    string ClassName = String.Empty;
                    string ExecuteFile = string.Empty;
                    string AssemblyName = String.Empty;

                    var Extension = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//Extension");

                    if (Extension != null)
                    {
                        ClassName += Extension.GetAttribute("SpaceName").ToString();
                        ClassName += ".";
                        ClassName += Extension.GetAttribute("ClassName").ToString();

                        switch (XmlDoc.SelectSingleNode("//Runtime").FirstChild.Name)
                        {
                            case "Assembly":
                                AssemblyName = XmlDoc.SelectSingleNode("//Assembly").InnerText;
                                plugin = (AddInBase)CreateInstance.Instance(AssemblyName, ClassName, AssemblySourcePath);
                                break;
                            case "ExecuteFile":
                                ExecuteFile = XmlDoc.SelectSingleNode("//ExecuteFile").InnerText;
                                plugin = new ExecuteFileAddIn(ExecuteFile);
                                break;
                        }

                        if (plugin.Icon == null)
                            plugin.Icon = DevelopAssistant.Core.Properties.Resources.plus_shield;

                        var MenuItem = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//MenuItem");
                        plugin.IdentityID = MenuItem.GetAttribute("IdentityID").ToString();
                        plugin.Name = MenuItem.GetAttribute("Name").ToString();
                        plugin.Text = MenuItem.GetAttribute("Text").ToString();
                        plugin.Tooltip = MenuItem.GetAttribute("Tooltip").ToString();
                        plugin.Position = MenuItem.GetAttribute("Position").ToString();

                        var AddInname = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//AddInname");
                        plugin.Copyright = new CopyRight();
                        plugin.Copyright.Author = AddInname.GetAttribute("Author").ToString();
                        plugin.Copyright.Description = AddInname.GetAttribute("Description").ToString();
                        plugin.Copyright.Version = AddInname.GetAttribute("Version").ToString();

                    }

                    bool isInstalled = true;
                    var element = XmlDoc.SelectSingleNode("//Uninstall");
                    if (element != null)
                    {
                        string isUninstalled = element.InnerText;
                        if (isUninstalled == "True")
                        {
                            isInstalled = false;
                        }
                    }

                    if (isInstalled)
                        list.Add(plugin);
                }

                Message = "加载插件成功";
            }
            catch (Exception ex)
            {
                DevelopAssistant.Common.NLogger.WriteToLine(ex.Message, "错误", DateTime.Now, ex.Source, ex.StackTrace);
                Message = "加载插件时发生错误,错误信息："+ex.Message;
            }            

            return list;
        }

        public List<AddInBase> List(ref string Message)
        {
            List<AddInBase> list = new List<AddInBase>();
            if (!System.IO.Directory.Exists(PluginSourcePath))
                System.IO.Directory.CreateDirectory(PluginSourcePath);

            string[] PluginsFiles = System.IO.Directory.GetFiles(PluginSourcePath, "*.AddIn");

            try
            {
                foreach (string file in PluginsFiles)
                {
                    AddInBase plugin = new AddInBase();
                    System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
                    XmlDoc.Load(file);

                    //...                    
                    string ClassName = String.Empty;
                    string ExecuteFile = string.Empty;
                    string AssemblyName = String.Empty;

                    var Extension = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//Extension");

                    if (Extension != null)
                    {
                        ClassName += Extension.GetAttribute("SpaceName").ToString();
                        ClassName += ".";
                        ClassName += Extension.GetAttribute("ClassName").ToString();

                        switch (XmlDoc.SelectSingleNode("//Runtime").FirstChild.Name)
                        {
                            case "Assembly":
                                AssemblyName = XmlDoc.SelectSingleNode("//Assembly").InnerText;
                                plugin = (AddInBase)CreateInstance.Instance(AssemblyName, ClassName, AssemblySourcePath);
                                break;
                            case "ExecuteFile":
                                ExecuteFile = XmlDoc.SelectSingleNode("//ExecuteFile").InnerText;
                                plugin = new ExecuteFileAddIn(ExecuteFile);
                                break;
                        }

                        if (plugin.Icon == null)
                            plugin.Icon = DevelopAssistant.Core.Properties.Resources.plus_shield;

                        var MenuItem = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//MenuItem");
                        plugin.IdentityID = MenuItem.GetAttribute("IdentityID").ToString();
                        plugin.Name = MenuItem.GetAttribute("Name").ToString();
                        plugin.Text = MenuItem.GetAttribute("Text").ToString();
                        plugin.Tooltip = MenuItem.GetAttribute("Tooltip").ToString();
                        plugin.Position = MenuItem.GetAttribute("Position").ToString();

                        var AddInname = (System.Xml.XmlElement)XmlDoc.SelectSingleNode("//AddInname");
                        plugin.Copyright = new CopyRight();
                        plugin.Copyright.Author = AddInname.GetAttribute("Author").ToString();
                        plugin.Copyright.Description = AddInname.GetAttribute("Description").ToString();
                        plugin.Copyright.Version = AddInname.GetAttribute("Version").ToString();

                    }

                    
                    plugin.Uninstall = false;
                    var element = XmlDoc.SelectSingleNode("//Uninstall");
                    if (element != null)
                    {
                        string isUninstalled = element.InnerText;
                        if (isUninstalled == "True")
                        {
                            plugin.Uninstall = true;                            
                        }
                    }

                    list.Add(plugin);
                       
                }

                Message = "加载插件成功";
            }
            catch (Exception ex)
            {
                DevelopAssistant.Common.NLogger.WriteToLine(ex.Message, "错误", DateTime.Now, ex.Source, ex.StackTrace);
                Message = "加载插件时发生错误,错误信息：" + ex.Message;
            }

            return list;
        }

        public bool Uninstall(string id)
        {
            try
            {
                string[] PluginsFiles = System.IO.Directory.GetFiles(PluginSourcePath, "*.AddIn");
                foreach (string file in PluginsFiles)
                {
                    System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
                    XmlDoc.Load(file);
                    var AddIn = XmlDoc.SelectSingleNode("//AddIn");
                    var Menuitem = XmlDoc.SelectSingleNode("//MenuItem");
                    string IdentityID = Menuitem.Attributes["IdentityID"].Value;
                    if (IdentityID.Equals(id, StringComparison.OrdinalIgnoreCase))
                    {
                        var element = XmlDoc.SelectSingleNode("//Uninstall");
                        if (element != null)
                        {
                            element.InnerText = "True";
                        }
                        else
                        {
                            element = XmlDoc.CreateElement("Uninstall");
                            element.InnerText = "True";
                            AddIn.AppendChild(element);
                        }
                        XmlDoc.Save(file);
                        break;
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                NLogger.WriteToLine(ex.Message, "错误", DateTime.Now, ex.Source, ex.StackTrace);
            }
            return false;
        }

        public bool Install(string id)
        {
            try
            {
                string[] PluginsFiles = System.IO.Directory.GetFiles(PluginSourcePath, "*.AddIn");
                foreach (string file in PluginsFiles)
                {
                    System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument();
                    XmlDoc.Load(file);
                    var AddIn = XmlDoc.SelectSingleNode("//AddIn");
                    var Menuitem = XmlDoc.SelectSingleNode("//MenuItem");
                    string IdentityID = Menuitem.Attributes["IdentityID"].Value;
                    if (IdentityID.Equals(id, StringComparison.OrdinalIgnoreCase))
                    {
                        var element = XmlDoc.SelectSingleNode("//Uninstall");
                        if (element != null)
                        {
                            AddIn.RemoveChild(element);
                        }                       
                        XmlDoc.Save(file);
                        break;
                    }                    
                }
                return true;
            }
            catch (Exception ex)
            {
                NLogger.WriteToLine(ex.Message, "错误", DateTime.Now, ex.Source, ex.StackTrace);
            }
            return false;
        }

    }
}
